package log

import (
	"errors"
	"os"
	"sync"
	"time"
)

type PoolItem struct {
	CreateAt *time.Time
	UseTime  *time.Time
	Out      *os.File
}

type PoolLog struct {
	Pool            map[string]PoolItem
	Max             int
	IsStartTimeTick bool
	m               sync.RWMutex
}

func NewPool(max int) *PoolLog {
	return &PoolLog{
		Pool: map[string]PoolItem{},
		Max:  max,
	}
}

func (p *PoolLog) Get(key string) *os.File {
	p.m.Lock()
	poolItem, ok := p.Pool[key]

	if ok {
		now := time.Now()
		poolItem.UseTime = &now
		p.Pool[key] = poolItem
	}
	p.m.Unlock()

	if ok {
		return poolItem.Out
	} else {
		return nil
	}
}

func (p *PoolLog) Has(key string) bool {
	p.m.RLock()
	_, ok := p.Pool[key]
	p.m.RUnlock()

	return ok
}

func (p *PoolLog) startTimeTickCheckInacvie() {
	if p.IsStartTimeTick {
		return
	}

	ticker := time.NewTicker(time.Minute * 60)

	for range ticker.C {
		now := time.Now()

		p.m.Lock()
		for key, value := range p.Pool {
			// 判断使用时间是否超过5分钟
			if value.UseTime != nil {
				if now.Sub(*value.UseTime) > 5*time.Minute {
					value.Out.Close()
					delete(p.Pool, key)
				}
			} else if now.Sub(*value.CreateAt) > 5*time.Minute {
				// 判断创建时间是否超过5分钟
				value.Out.Close()
				delete(p.Pool, key)
			}
		}
		p.m.Unlock()
	}

}

func (p *PoolLog) Set(key string, out *os.File) error {

	if len(p.Pool) == p.Max {
		return errors.New("文件流池已满")
	}

	now := time.Now()
	p.m.Lock()
	p.Pool[key] = PoolItem{
		CreateAt: &now,
		Out:      out,
	}
	p.m.Unlock()

	go p.startTimeTickCheckInacvie()

	return nil
}
